package com.jdk.learn.thread;

/**
 * package com.jdk.learn.thread;
 * <p>
 * public class SynRecompileDemo implements Runnable {
 * private volatile Integer ticket = new Integer(200);
 * <p>
 * public SynRecompileDemo() {
 * }
 * <p>
 * public void run2() {
 * Integer var1 = this.ticket;
 * synchronized(this.ticket) {
 * for(int i = 0; i < 200; ++i) {
 * if (this.ticket > 0) {
 * Integer var3 = this.ticket;
 * Integer var4 = this.ticket = this.ticket - 1;
 * }
 * }
 * <p>
 * }
 * }
 * <p>
 * public void run() {
 * synchronized(this) {
 * for(int i = 0; i < 200; ++i) {
 * if (this.ticket > 0) {
 * Integer var3 = this.ticket;
 * Integer var4 = this.ticket = this.ticket - 1;
 * }
 * }
 * <p>
 * }
 * }
 * }
 *
 *
 * cmd命令行执行：javap -verbose SynRecompileDemo.class >>SynRecompile.txt
 *
 *
 */
public class SynRecompileDemo2 implements Runnable {
    private volatile Integer ticket = new Integer(300);

    /**
     * 说明当线程过来时
     *      ticket初始值是200 此时只有一个线程可以获取到200这个线程 假定线程A持有
     *          A这个线程先执行  此时值改为199  进入等待  此时持有的对象是200对象 还未释放
     *          BC线程继续轮询  发现ticket变为199 则199 在剩下的线程中只能有一个持有 假定为线程B
     *          B继续执行 将ticket改为198   进入等待  C继续轮询 发现198对象无线程持有 占用198
     *              依次类推...
     *
     *              看到的现象是交替执行
     */
    @Override
    public void run() {
        synchronized (ticket) {
                System.out.println("-----name:"+Thread.currentThread().getName()+"获取到锁."+ticket);
            for (int i = 0; i < 10; i++) {
                if (ticket > 0) {
                    try {
                        //如果--在前的话  栈帧没操作完毕就开始操作sleep了
                        /**
                         54: if_icmpge     143
                         57: aload_0
                         58: getfield      #4                  // Field ticket:Ljava/lang/Integer;
                         61: invokevirtual #16                 // Method java/lang/Integer.intValue:()I
                         64: ifle          143
                         67: aload_0
                         68: getfield      #4                  // Field ticket:Ljava/lang/Integer;
                         71: astore_3
                         72: aload_0
                         73: aload_0
                         74: getfield      #4                  // Field ticket:Ljava/lang/Integer;
                         77: invokevirtual #16                 // Method java/lang/Integer.intValue:()I
                         80: iconst_1
                         81: isub
                         ---------------------------------------------
                         82: invokestatic  #17                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
                         85: dup_x1
                         86: putfield      #4                  // Field ticket:Ljava/lang/Integer;
                         89: astore        4
                         91: aload_3
                         92: pop
                         93: ldc2_w        #18                 // long 5l
                         96: invokestatic  #20                 // Method java/lang/Thread.sleep:(J)V
                         99: goto          107
                         ----------------------------------------------------------------------------------------
                         102: astore_3
                         103: aload_3
                         104: invokevirtual #22                 // Method java/lang/Exception.printStackTrace:()V
                         107: getstatic     #5                  // Field java/lang/System.out:Ljava/io/PrintStream;
                         110: new           #6                  // class java/lang/StringBuilder
                         113: dup
                         114: invokespecial #7                  // Method java/lang/StringBuilder."<init>":()V
                         117: ldc           #23                 // String name:
                         */
                        ticket--;//如果改完后进行等待  则三个线程交替执行  乱序 因为值已经发生变量  且各线程知悉  这时候锁的对象不一致了。
                        Thread.sleep(5);//sleep会放弃cpu使用权 然后大家依次竞争cpu的使用权  但是持有当前锁ticket的值

                        /**
                         51: iload_2
                         52: bipush        10
                         54: if_icmpge     143
                         57: aload_0
                         58: getfield      #4                  // Field ticket:Ljava/lang/Integer;
                         61: invokevirtual #16                 // Method java/lang/Integer.intValue:()I
                         64: ifle          143
                         67: ldc2_w        #17                 // long 5l
                         70: invokestatic  #19                 // Method java/lang/Thread.sleep:(J)V
                         ---------------------------------------------------------
                         73: aload_0
                         74: getfield      #4                  // Field ticket:Ljava/lang/Integer;
                         77: astore_3
                         78: aload_0
                         79: aload_0
                         80: getfield      #4                  // Field ticket:Ljava/lang/Integer;
                         83: invokevirtual #16                 // Method java/lang/Integer.intValue:()I
                         86: iconst_1
                         87: isub
                         88: invokestatic  #20                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
                         91: dup_x1
                         92: putfield      #4                  // Field ticket:Ljava/lang/Integer;
                         95: astore        4
                         97: aload_3
                         98: pop
                         99: goto          107
                         102: astore_3
                         103: aload_3
                         ------------------------------------------------
                         104: invokevirtual #22                 // Method java/lang/InterruptedException.printStackTrace:()V
                         107: getstatic     #5                  // Field java/lang/System.out:Ljava/io/PrintStream;
                         110: new           #6                  // class java/lang/StringBuilder
                         113: dup
                         114: invokespecial #7                  // Method java/lang/StringBuilder."<init>":()V
                         117: ldc           #23                 // String name:
                         119: invokevirtual #9                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
                         122: invokestatic  #10                 // Method java/lang/Thread.currentThread:()Ljava/lang/Thread;
                         125: invokevirtual #11                 // Method java/lang/Thread.getName:()Ljava/lang/String;
                         128: invokevirtual #9                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
                         131: invokevirtual #14                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
                         134: invokevirtual #15                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
                         137: iinc          2, 1
                         140: goto          51
                         */
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                System.out.println("name:"+Thread.currentThread().getName());
                } else {
                    break;
                }
            }
        }
    }


    public static void main(String[] args) throws InterruptedException {
        SynRecompileDemo2 sd=new SynRecompileDemo2();
        new Thread(sd).start();
        Thread.sleep(5);
        new Thread(sd).start();
        Thread.sleep(5);
        new Thread(sd).start();

        /**
         * 结果可能是如下 也可能是300 299 298这样等等


         -----name:Thread-0获取到锁.300
         -----name:Thread-2获取到锁.299
         name:Thread-2
         name:Thread-0
         name:Thread-2
         name:Thread-0
         name:Thread-2
         name:Thread-0
         name:Thread-0
         name:Thread-2
         name:Thread-0
         name:Thread-2
         name:Thread-0
         name:Thread-2
         name:Thread-0
         name:Thread-2
         name:Thread-0
         name:Thread-2
         name:Thread-0
         name:Thread-2
         name:Thread-0
         -----name:Thread-1获取到锁.280
         name:Thread-2
         name:Thread-1
         name:Thread-1
         name:Thread-1
         name:Thread-1
         name:Thread-1
         name:Thread-1
         name:Thread-1
         name:Thread-1
         name:Thread-1
         name:Thread-1

         *
         */
    }
}
